package structs

import (
	"encoding/json"
	"fmt"
	"reflect"
	"strings"

	"gorm.io/datatypes"
)

type StructField struct {
	reflect.StructField
}

func (f *StructField) JsonName() string {
	tagString := f.Tag.Get("json")
	if tagString == "_" {
		return ""
	} else if tagString == "" {
		return f.Name
	} else {
		parts := strings.Split(tagString, ",")
		return parts[0]
	}
}

func (f *StructField) IsStruct() bool {
	kind := reflect.TypeOf(f).Kind()
	return kind == reflect.Struct
}

func (f *StructField) JsonIgnored() bool {
	tagString := f.Tag.Get("json")
	return tagString == "-"
}

func (f *StructField) JsonOmitEmpty() bool {
	tagString := f.Tag.Get("json")
	return strings.Contains(tagString, ",omitempty")
}

func StructType(v any) reflect.Type {
	vtype := reflect.TypeOf(v)
	if vtype.Kind() == reflect.Ptr {
		vtype = vtype.Elem()
	}
	return vtype
}

// 根据对象类型过滤map数据
func FilterDataByObject(obj any, data map[string]any) map[string]any {
	var result = map[string]any{}
	for k, v := range data {
		modelType := StructType(obj)
		for i := 0; i < modelType.NumField(); i++ {
			f := StructField{StructField: modelType.Field(i)}
			if f.JsonName() == k {
				if v == "null" {
					v = nil
				}
				fieldType := fmt.Sprintf("%v", f.Type)
				if fieldType == "datatypes.JSON" {
					var jsonVal datatypes.JSON
					if vstr, err := json.Marshal(v); err != nil {
						panic(err)
					} else {
						json.Unmarshal([]byte(vstr), &jsonVal)
						result[k] = jsonVal
					}
				} else {
					result[k] = v
				}
				break
			}
		}
	}
	return result
}
